import hxbase.events.Event;
//import hxbase.events.EventArray;

#if flash9
 import flash.events.EventDispatcher;

class FEvent extends flash.events.Event
{
	public static var dispatcher = new EventDispatcher();
	
	public var msg : Int;
	public function new() {
		msg = 888;
		super('888FE');
	}
}
#end

class SpeedEvent extends EventGroup
{
	var zoof : Event< Int -> Void >;	
}
/*
class SpeedEventArray extends EventGroupArray
{
	var zoof : Event2< Int -> String -> Void >;	
}*/

class VeryBasicSpeedtest
{
	var event : SpeedEvent;
//	var event2 : SpeedEventArray;
	#if flash9	
	var event2 : EventDispatcher;
	#end
	
	var countdown	: Int;
	var count		: Int;
	var start		: Int;
	var end			: Int;
	var endBind		: Int;
	
	var time : Dynamic;
	
	public function new()
	{
		countdown = 60;
		#if flash
		time = flash.Lib.getTimer;
		#else neko
		time = function(){ return 1000 * neko.Sys.time(); };
		#else js
		time = Date.now;
		#end
		eventGroupTest();
		runTest1();
		#if flash9
		runTest2();
		#end
	}
	
	function eventGroupTest()
	{
		event = null;
		count = 0;
		start = time();
		for(x in 0 ... 200) {
			event = new SpeedEvent();
			untyped EventGroup.rttiCache = [];
			count++;
		}
		event = new SpeedEvent();
		end	  = time();
		trace("EventGroupTest( "+count+" ) -- Instantiate EventGroup (parse rtti xml): "+ (end - start) );
		
		event = null;
		count = 0;
		start = time();
		for(x in 0 ... 200) {
			event = new SpeedEvent();
			count++;
		}
		end	  = time();
		trace("EventGroupTest( "+count+" ) -- Instantiate EventGroup (with rtti cache): "+ (end - start) );
			
		//event2 = new SpeedEventArray();
	}
	
	function runTest1()
	{
		for(x in 0 ... 5) {
			trace('---');
			count = 0;
			bubbleTest();
			trace("BubbleTest( "+x+" ) -- Binding: "+ (endBind - start) );
			trace("BubbleTest( "+x+" ) -- Dispatch: "+ (end - endBind) );
			var s = time();
			event.zoof.unbind(this);//,handler);
			trace("BubbleTest( "+x+" ) -- Unbind listers ("+count+"): "+ (time() - s) );
			trace("BubbleTest( "+x+" ) -- Total: "+ (time() - start) );
		}
	}
	
	#if flash9
	function runTest2()
	{
		event2 = FEvent.dispatcher;
		for(x in 0 ... 5) {
			count = 0;
			flashTest();
			trace("FlashTest( "+x+" ) -- Total: "+ (end - start) );
			trace("FlashTest( "+x+" ) -- Binding: "+ (endBind - start) );
			trace("FlashTest( "+x+" ) -- Dispatch: "+ (end - endBind) );
			var s = time();
			//event2.removeEventListener('888FE', handler);
			event2 = new EventDispatcher();
			trace("FlashTest( "+x+" ) -- Unbind listers ("+count+"): "+ (time() - s) );
		}
	}
	
	function flashTest()
	{
		start = time();
		var me = this;
		for(x in 0 ... 10000) event2.addEventListener('888FE', 
			function ( x:Dynamic ) {me.count++;}
			//handler
		);
		endBind = time();
		
		event2.dispatchEvent( new FEvent() );
		
		end = time();
	}
	#end
	
	function bubbleTest()
	{	
		start = time();
		for(x in 0 ... 10000) event.zoof.bind(this, handler);
		endBind = time();
		
		event.zoof.call(10000);
		
		end = time();
	}
	/*
	function arrayTest()
	{
		start = time();
		for(x in 0 ... 10000) event2.zoof.bind(this, handler);
		endBind = time();
		
		event2.zoof.call(10000, "Hello world!");
		
		end = time();
	}*/
	
	function handler( x:Dynamic ) {
		count++;
	}
	
	public static function main()
	{
		new VeryBasicSpeedtest();
	}
}